define(function (require, exports, module) {
    /**
     * @description Name of the signature tool.
     * @constant
     * @type {String}
     */
    WebPDF.Tools.TOOL_NAME_SIGNATURE = "Signature";

    /**
     * @description Tool handler of signature.
     * @extends WebPDF.Tools.IReaderToolHandler
     * @constructor
     * @return instance of signature plugin.
     */
    WebPDF.Tools.SignatureToolHandler = function (readerApp, signaturePlugin) {
        var _bLeftMouseDown = false,
        	_curPageView = null,
        	_isCursorInitialized = false,
            _readerApp = readerApp,
            _signaturePlugin = signaturePlugin,
            _signatureCursorClass = "",
            _self = this,
            _signHoverDivId = "";

        /**
         * initialize cursor
         * @private
         */
        function _initCursor() {
            var mainView = _readerApp.getMainView();
            if (mainView !== null) {
                if (!_isCursorInitialized) {
                    var docView = mainView.getDocView();
                    $("#" + docView.getDocViewContainerID()).addClass(_signatureCursorClass);
                    _isCursorInitialized = true;
                }
            }
            else {
                //wait util the viewer has been created
                setTimeout(_initCursor, 100);
            }
        }
        
        function _updateSignHoverDiv(bShow, eventPageX, eventPageY) {
        	var signHoverDiv = $("#" + _signHoverDivId);
        	if (bShow) {
        		if ((eventPageX == null || eventPageY == null) &&
        				document.event && document.event.pageX && document.event.pageY) {
        			eventPageX = document.event.pageX;
        			eventPageY = document.event.pageY;
        		}
        		if (eventPageX != null && eventPageY != null) {
                	var docView = _readerApp.getMainView().getDocView();
                    var docViewRect = docView.getDocViewClientRect();
                    if (WebPDF.RectUtils.ptInRect(docViewRect, eventPageX, eventPageY)){
                    	var containerObj = $("#" + docView.getDocViewContainerID());
                    	var containerLeft = parseInt(containerObj.css("left"));
                    	var containerTop = parseInt(containerObj.css("top"));
                    	if (!containerLeft) {
                    		containerLeft = 0;
                    	}
                    	if (!containerTop) {
                    		containerTop = 0;
                    	}
                    	var left = Math.max(0,(eventPageX - docViewRect.left + containerLeft - signHoverDiv.outerWidth()/2))+'px';
                        var top = Math.max(0,(eventPageY - docViewRect.bottom + containerTop - signHoverDiv.outerHeight()/2))+'px';     
                        signHoverDiv.css({left: left, top: top});
                    }
                }
        		if (!signHoverDiv.is(":visible"))
        			signHoverDiv.show();
        	} else {
        		signHoverDiv.hide();
        	}
        }
        
        this.updateCursor = function(curSignatureId) {
        	var signatureCursorClass = "fwr-sign-cursor";
        	if (curSignatureId == WebPDF.PDFData.BaseSignature.Date) {
        		signatureCursorClass = "fwr-sign-date-cursor";
        		_updateSignHoverDiv(false);
    		} else if (curSignatureId == WebPDF.PDFData.BaseSignature.Text) {
    			signatureCursorClass = "fwr-sign-text-cursor";
    			_updateSignHoverDiv(false);
    		} else {
    			var singnatureObj = _signaturePlugin.getCurSingnature();
    			if (singnatureObj) {
    				$("#" + _signHoverDivId + " img").attr('src',singnatureObj.getFilePath());
    				_updateSignHoverDiv(true, null, null);
    			}
    		}
        	if (WebPDF.Environment.ie || WebPDF.Environment.ieAtLeast11)
        		signatureCursorClass += "-ie";
        	var mainView = _readerApp.getMainView();
        	if (signatureCursorClass != _signatureCursorClass) {
        		if (mainView) {
        			var docView = mainView.getDocView();
                    $("#" + docView.getDocViewContainerID()).removeClass(_signatureCursorClass).addClass(signatureCursorClass);
                    _signatureCursorClass = signatureCursorClass;
        		} else {
        			setTimeout(_initCursor, 100);
        		}
        	}      	
        };
        
        this.bindInputEvent = function(inputId) {
        	var inputObj = document.getElementById(inputId);
        	if (WebPDF.Environment.ie) {
        		inputObj.attachEvent("onpropertychange", _adjustSignatureInputArea);
        		$(inputObj).keyup(function(event){ 
        			var code = event.keyCode||event.which;
        			if (code == 8 || code == 46 || (event.ctrlKey && code == 88)) {//backspace delete ctrl+x
        				_adjustSignatureInputArea(event,true);
        			}
        		});
            } else {//非IE
            	inputObj.addEventListener("input", _adjustSignatureInputArea, false);
            }
        };
        
        this.onInit = function () {            
            var mainFrameID = _readerApp.getMainView().getMainFrameID();
            _signHoverDivId = mainFrameID + "_signHover";        
             $("#" + mainFrameID).append("<div id='" + _signHoverDivId + "' style='z-order:99;position:absolute;display:none;'><img class='fwr-signature-hover-img'></img></div>");
        };

        this.onDestroy = function () {
        };

        this.getName = function () {
            return WebPDF.Tools.TOOL_NAME_SIGNATURE;
        };

        this.onActivate = function () {
        	_self.updateCursor();
        };

        this.onDeactivate = function () {
        	var mainView = _readerApp.getMainView();
            if (mainView) {
                var docView = mainView.getDocView();
                $("#" + docView.getDocViewContainerID()).removeClass(_signatureCursorClass);
            }
            _isCursorInitialized = false;
            _signatureCursorClass = "";
            _updateSignHoverDiv(false);
        };

        this.isEnabled = function () {
            return true;
        };

        this.isProcessing = function () {
            return _bLeftMouseDown;
        };

        this.onLButtonDown = function (event) {
        	if($(event.target).hasClass("fwr-signature") || 
        			$(event.target).parent().hasClass("fwr-signature")){
            	return false;
            }
        	
        	_curPageView = null;
        	
        	var docView = _readerApp.getMainView().getDocView();
            var docViewRect = docView.getDocViewClientRect();
            if (!WebPDF.RectUtils.ptInRect(docViewRect, event.pageX, event.pageY))
                return true;
            var jqDocViewContainer = $("#" + docView.getDocViewContainerID());
            if (!WebPDF.Common.containsNode(jqDocViewContainer.get(0), event.target, true)) {
                return false;
            }
            
            if (WebPDF.Environment.ieAtLeast11)
            {
                //让鼠标在拖动时不会变成文本选中状态,同时解决ie11下面拖动页面不正常的bug
                WebPDF.Common.preventDefaults(event, true);
            }
            
            var visiblePageRange = _readerApp.getDocView().getVisiblePageRange();
            var pageViewInfo = _signaturePlugin.getPageViewInfo(visiblePageRange,docView,event.pageX,event.pageY);
            if (pageViewInfo)
            	_curPageView = pageViewInfo.pageView;
            _bLeftMouseDown = true;
            if (_curPageView && _curPageView.isPageLoaded() && !_curPageView.isPageLoadError()) {
            	var pageViewRect = pageViewInfo.pageViewRect;
            	_updateSignHoverDiv(false);
            	var singnatureObj = _signaturePlugin.getCurSingnature();
                _signaturePlugin.addSingnatureToPage(_curPageView, singnatureObj, event.pageX - pageViewRect.left, event.pageY - pageViewRect.bottom, _addSingnatureToPageCallback);
            }
            
		    return false;
        };
        
        function _addSingnatureToPageCallback(singnatureDocObj) {
        	if (singnatureDocObj) {
            	var signatureContainerId = _signaturePlugin.getSignatureContainerId(_curPageView);
            	var signatureObjId = signatureContainerId + '_' + singnatureDocObj.getId();
            	if (singnatureDocObj.getType() == WebPDF.PDFData.SignatureType.Text) {
            		var inputId = signatureObjId + "_input";
            		var inputObj = $("#" + inputId);
            		if(singnatureDocObj.getSignatureId() == WebPDF.PDFData.BaseSignature.Date){
            			inputObj.select();
	            	}
            		_self.bindInputEvent(inputId);
            		inputObj.focus();
            	}
            	WebPDF.ViewerInstance.setCurrentToolByName(WebPDF.Tools.TOOL_NAME_HAND);
            }
        }

        this.onLButtonUp = function (event) {
        	if (_bLeftMouseDown) {
                _bLeftMouseDown = false;
        	}  
            return false;;
        };

        this.onLButtonDblClk = function (event) {
            return false;
        };

        this.onMouseMove = function (event) {
            if($("#" + _signHoverDivId).is(":visible")){
            	_updateSignHoverDiv(true, event.pageX, event.pageY);
            }
        	return true;
        };

        this.onRButtonDown = function (event) {
            return false;
        };

        this.onRButtonUp = function (event) {
            return false;
        };

        this.onRButtonDblClk = function (event) {
            return false;
        };

        this.onMouseWheel = function (event) {
            return false;
        };

        this.onMouseOver = function (event) {
        	return false;
        };

        this.onMouseOut = function (event) {
        	return false;
        };

        this.onMouseEnter = function (event) {
            return false;
        };

        this.onMouseLeave = function (event) {
        	if (_bLeftMouseDown) {
                _bLeftMouseDown = false;
            }
            return true;
        };

        this.onDoubleTap = function(event) {
            return false;
        };
        this.onPinchIn = function(event) {
            return false;
        };
        this.onPinchOut = function(event) {
            return false;
        };
        this.onHold = function(event) {
            return false;
        };
        
        /*
         *  计算字符串的宽度
         *  @private
         *  @param {!value} value 字符串
         *  @param {!Object} spanObj 存放字符串的span标签的jQuery对象
         */
        function _calcuStrWidth(value, spanObj) {
            var width = 0;
            if (value != null && value != "") {
                spanObj.html(value.replace(/ /g, '&nbsp;'));
                width = spanObj.width();
                var lineNum = parseInt(spanObj.height() / 10);
                if (lineNum > 1) {
                    var lineCharNum = parseInt(value.length / lineNum) + 1;
                    width = 0;
                    for (var i = 0; i < lineNum; i++) {
                        spanObj.html(value.substr(lineCharNum * i, lineCharNum).replace(/ /g, '&nbsp;'));
                        width += spanObj.width();
                    }
                }
            }
            return width;
        }
        
        /*
         *  Signature 编辑时，其区域计算并调整
         *  @private
         *  @param {Object} event 一些事件处理传入的对象
         */
        function _adjustSignatureInputArea(event,bKeyUp) {
            if (!bKeyUp && event && WebPDF.Environment.ie && event.propertyName != "value")
                return;
            
            var editObj = $(this);
            if (event && event.target) {
            	editObj = $(event.target);
            } else if (event && event.srcElement) {
            	editObj = $(event.srcElement);
            }
            var curObject = editObj.parent();
            var id = "SpellCeckSpan" + (new Date()).valueOf().toString();
            var spanCode = '<span id= "' + id + '" style= "position: absolute;visibility:hidden;border:0;padding:0;line-height:10px;font-size:' + editObj.css("font-size") + ';font-family:' + editObj.css("font-family") + ';"></span>';
            editObj.after(spanCode);
            var tmpSpanObj = $("#" + id);
            //解决空格测不出长度问题;
            var value = editObj.val();
            if(value){
            	editObj.removeClass("fwr-sign-input-placeholder");
            }else{
            	editObj.addClass("fwr-sign-input-placeholder");
            }
            var strArray = value.split('\n');
            var rowCount = strArray.length;
            var widthArray = new Array(rowCount);
            var maxLineWidth = 0;
            var minCharWidth = 0;
            for (var i = 0; i < rowCount; i++) {
                widthArray[i] = _calcuStrWidth(strArray[i], tmpSpanObj);
                maxLineWidth = Math.max(maxLineWidth, widthArray[i]);
                if (strArray[i].length > 0) {
                    if (minCharWidth == 0) {
                        minCharWidth = widthArray[i] / strArray[i].length;
                    } else {
                        minCharWidth = Math.min(minCharWidth, widthArray[i] / strArray[i].length);
                    }
                }
            }
            tmpSpanObj.remove();
            
            var idStrArray = curObject.attr("id").split("_");
        	var curIndex = parseInt(idStrArray[idStrArray.length - 3]);
            var curPageView = _readerApp.getMainView().getDocView().getPageView(curIndex);
            var signatureId = _signaturePlugin.getSignatureDocObjIdFromObj(curObject);
			var signatureDocObj = _signaturePlugin.getSingnatureFromPage(signatureId, curPageView);
            var pageWidth = curPageView.getPageViewWidth() - 23;
            var pageHeight = curPageView.getPageViewHeight() - 12;
            var scale = curPageView.getScale();
            var desRect = new WebPDF.PDFRect;
            desRect.left = Math.max(0, parseFloat(curObject.css("left")));
            desRect.top = Math.max(0, parseFloat(curObject.css("top")));
            desRect.right = desRect.left + curObject.width();
            desRect.bottom = desRect.top + curObject.height();
            
            //////先计算宽度
            var bChangeRect = false;
            var minWidth = 100 * scale;
            if (maxLineWidth < minWidth) {
            	maxLineWidth = minWidth;
            }
            var currentWidth = WebPDF.RectUtils.width(desRect);
            var needWidth = maxLineWidth - currentWidth + minCharWidth / 2;
            if (needWidth != 0) {
            	var desRight = desRect.right + needWidth;
            	if (desRight > pageWidth) {
            		desRect.left = Math.max(0, desRect.left + pageWidth - desRight);
            		desRight = pageWidth;
            	}
            	desRect.right = desRight;
            	curObject.css({
                    left: parseInt(desRect.left + 0.5) + "px",
                    width: parseInt(WebPDF.RectUtils.width(desRect) + 0.5) + "px"
                });

                bChangeRect = true;
            }
            
            //////再计算高度
            var tmpEditObj = $(editObj.get(0).outerHTML);
            tmpEditObj.height(26).attr("id","").css("z-index","0").val(value);
            editObj.after(tmpEditObj);
            var desBottom = desRect.top + tmpEditObj.get(0).scrollHeight;
            tmpEditObj.remove();
			if (desRect.bottom != desBottom) {
				if (desBottom > pageHeight) {
	            	desRect.top = Math.max(0, desRect.top + pageHeight - desBottom);
	            	desBottom = pageHeight;
	            }
	            desRect.bottom = desBottom;
	            var minHeight = 26 * scale;
            	if (desRect.bottom - desRect.top < minHeight) {
            		desRect.bottom = Math.min(pageHeight, desRect.top + minHeight);
            		if (desRect.bottom - desRect.top < minHeight) {
            			desRect.top = Math.max(0, desRect.bottom - minHeight);
            		}
            	}
				bChangeRect = true;
			}
			
			if (bChangeRect) {
	            curObject.css({
	                top: parseInt(desRect.top + 0.5) + "px",
	                height: parseInt(WebPDF.RectUtils.height(desRect) + 0.5) + "px"
	            });
			}
			//保存数据
			signatureDocObj.setPosX(parseInt(desRect.left / scale + 0.5));
			signatureDocObj.setPosY(parseInt(desRect.top / scale + 0.5));
			signatureDocObj.setWidth(parseInt(WebPDF.RectUtils.width(desRect) / scale + 0.5));
			signatureDocObj.setHeight(parseInt(WebPDF.RectUtils.height(desRect) / scale + 0.5)); 
			signatureDocObj.setSignatureText(value);
        }
    };

    return WebPDF.Tools.SignatureToolHandler;
});